/*
 * VeriSimPrefs.java
 * 
 * last update: 14.01.2010 by Stefan Saru
 * 
 * author:	Lucian Ghita Felix(felix@ulise.cs.pub.ro)
 *
 * Obs: N/A
 */

package ide;

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.metal.*;


/**
 * This is dialog which allows users to choose preferences
 * and made me have a terrible pain in the ass for a long time
 * @version 1.0
 * @author fEliX
 */
@SuppressWarnings("serial")
public class VeriSimPrefs extends JDialog {

	VeriSimFrame god;

	private JDialog thisPanel;   //for use inside the inner actions.




	ButtonGroup indentGroup;
	JTextField tabField;
	JTextField mrfField;
	JTextField mrpField;
	JCheckBox autosaveCheck;
	JTextField autosaveField;
	JCheckBox backupCheck;
	JCheckBox loadLastProjectCheck;
	JTextField undoField;
	ButtonGroup saveGroup;  
	ButtonGroup plafGroup;
	ButtonGroup themeGroup;

	JList includeList;
	JList modulesList;


	JCheckBox saveBeforeRun;



	public VeriSimPrefs(JFrame f) {
		super(f, "Preferences", true);
		god = (VeriSimFrame) f;
		thisPanel = this;

		JPanel container = new JPanel();
		container.setLayout( new BorderLayout() );

		JTabbedPane tabs = new JTabbedPane();

		tabs.addTab( "General", null, buildTextPanel());
		tabs.addTab( "CR/LF?", null, buildCrlfPanel());
		tabs.addTab( "Look", null, buildPlafPanel() );
		tabs.addTab( "Interpretor", null, buildVerilogPanel() );
		tabs.addTab( "Directories", null, buildDirectoriesPanel() );


		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout ( new FlowLayout(FlowLayout.RIGHT) );
		JButton cancel = new JButton("Cancel");
		cancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				CancelPressed();
			}});
		buttonPanel.add( cancel );

		JButton ok = new JButton("OK");
		ok.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				OKPressed();
			}});
		buttonPanel.add( ok );
		getRootPane().setDefaultButton(ok);

		container.add(tabs, BorderLayout.CENTER);
		container.add(buttonPanel, BorderLayout.SOUTH);
		getContentPane().add(container);
		pack();
		centerDialog();
		setResizable(false); 

		god.fHash.print();
		//UIManager.addPropertyChangeListener(new UISwitchListener(container));
	}

	public JPanel buildTextPanel() {
		JPanel textPanel = new JPanel();
		//GridLayout gridLayout = new GridLayout(0, 1);
		//gridLayout.setVgap(3);
		textPanel.setLayout(new ColumnLayout());


		//  INDENTATION
		JPanel indentPanel = new JPanel();

		JPanel upperPanel = new JPanel();


		indentPanel.setLayout(new ColumnLayout());
		indentPanel.setBorder( new TitledBorder("Indent") );

		indentGroup = new ButtonGroup();
		JRadioButton noneIndent = new JRadioButton("none");
		JRadioButton defaultIndent = new JRadioButton("default");
		JRadioButton smartIndent = new JRadioButton("smart");
		//todo
		defaultIndent.setEnabled(false);
		smartIndent.setEnabled(false);

		noneIndent.getModel().setActionCommand("none");
		defaultIndent.getModel().setActionCommand("default");
		smartIndent.getModel().setActionCommand("smart");


		indentGroup.add(noneIndent);
		indentGroup.add(defaultIndent);
		indentGroup.add(smartIndent);

		indentPanel.add(noneIndent);
		indentPanel.add(defaultIndent);
		indentPanel.add(smartIndent);

		noneIndent.setSelected(((String)god.fHash.get("indentType")).equals("none"));
		defaultIndent.setSelected(((String)god.fHash.get("indentType")).equals("default"));
		smartIndent.setSelected(((String)god.fHash.get("indentType")).equals("smart"));

		upperPanel.add(indentPanel);

		JPanel rightPanel = new JPanel(new ColumnLayout());

		int val = 0;

		//  TAB SIZE
		JLabel tabLabel = new JLabel("tab size:");
		val = ((Integer)god.fHash.get("tabSize")).intValue();

		tabField = new JTextField(Integer.toString(val), 4);
		JPanel tabPanel = new JPanel(new FlowLayout());
		tabPanel.add(tabLabel);
		tabPanel.add(tabField);
		rightPanel.add(tabPanel);

		//  BACKUP
		backupCheck = new JCheckBox("Backup on save",((Boolean)god.fHash.get("autobackup")).booleanValue());
		//boolean bool = ((Boolean)god.fHash.get("autobackup")).booleanValue();
		//((JToggleButton.ToggleButtonModel)(backupCheck.getModel())).setSelected(((Boolean)god.fHash.get("autobackup")).booleanValue());
		rightPanel.add(backupCheck);

		loadLastProjectCheck = new JCheckBox("Load last project on startup",((Boolean)god.fHash.get("loadLastProject")).booleanValue());
		rightPanel.add(loadLastProjectCheck);


		//  MAX UNDO LEVEL
		JLabel undoLabel = new JLabel("Undo buffer size:");
		val = ((Integer)god.fHash.get("undoSize")).intValue();
		undoField = new JTextField(Integer.toString(val), 3);
		JPanel undoPanel = new JPanel(new FlowLayout());
		undoPanel.add(undoLabel);
		undoPanel.add(undoField);

		rightPanel.add(undoPanel);


		upperPanel.add(rightPanel);
		textPanel.add(upperPanel);


		//  MOST RECENT FILES LIST SIZE
		JLabel mrfLabel = new JLabel("Most recent files list size:");
		val = ((Integer)god.fHash.get("mrf")).intValue();
		mrfField = new JTextField(Integer.toString(val), 3);
		JPanel mrfPanel = new JPanel(new FlowLayout());
		mrfPanel.add(mrfLabel);
		mrfPanel.add(mrfField);
		textPanel.add(mrfPanel);



		//  MOST RECENT PROJECTS LIST SIZE
		JLabel mrpLabel = new JLabel("Most recent projects list size:");
		val = ((Integer)god.fHash.get("mrp")).intValue();
		mrpField = new JTextField(Integer.toString(val), 3);
		JPanel mrpPanel = new JPanel(new FlowLayout());
		mrpPanel.add(mrpLabel);
		mrpPanel.add(mrpField);
		textPanel.add(mrpPanel);
		//  AUTOSAVE
		autosaveCheck = new JCheckBox("Autosave ", ((Boolean)god.fHash.get("autosave")).booleanValue());
		JLabel autosave1Label = new JLabel(" every ");
		autosaveField = new JTextField(Integer.toString(((Integer)god.fHash.get("autosaveTime")).intValue()), 3);
		autosaveField.setEnabled( ((Boolean)god.fHash.get("autosave")).booleanValue());
		JLabel autosave2Label = new JLabel(" minutes");
		JPanel autosavePanel = new JPanel();
		autosavePanel.add(autosaveCheck);
		autosavePanel.add(autosave1Label);
		autosavePanel.add(autosaveField);
		autosavePanel.add(autosave2Label);

		autosaveCheck.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				autosaveField.setEnabled(((JToggleButton.ToggleButtonModel)(autosaveCheck.getModel())).isSelected());
			}});

		textPanel.add(autosavePanel);





		//todo:  get/update options from prefs file

		return textPanel;
	}

	public JPanel buildCrlfPanel() {
		JPanel panel = new JPanel();
		panel.setLayout( new GridLayout(1, 0) );

		JPanel savePanel = new JPanel();

		savePanel.setLayout(new ColumnLayout());
		savePanel.setBorder( new TitledBorder("Save text file using:") );
		saveGroup = new ButtonGroup();
		JRadioButton saveUnix = new JRadioButton("UNIX format");
		JRadioButton saveDos = new JRadioButton("DOS format");
		JRadioButton saveAuto = new JRadioButton("original format");

		saveUnix.getModel().setActionCommand("unix");
		saveDos.getModel().setActionCommand("dos");
		saveAuto.getModel().setActionCommand("auto");


		saveGroup.add(saveUnix);
		saveGroup.add(saveDos);
		saveGroup.add(saveAuto);

		savePanel.add(saveUnix);
		savePanel.add(saveDos);
		savePanel.add(saveAuto);

		saveAuto.setSelected(((String)god.fHash.get("saveType")).equals("auto"));
		saveUnix.setSelected(((String)god.fHash.get("saveType")).equals("unix"));
		saveDos.setSelected(((String)god.fHash.get("saveType")).equals("dos"));

		panel.add(savePanel);
		/*
    JPanel autoRespond = new JPanel();
    autoRespond.setLayout(new ColumnLayout());
    autoRespond.setBorder( new TitledBorder("Auto Response") );

    ButtonGroup respondGroup = new ButtonGroup();
    JRadioButton none = new JRadioButton("None");
    JRadioButton vaca = new JRadioButton("Send Vacation Message");
    JRadioButton thx = new JRadioButton("Send Thank You Message");

    respondGroup.add(none);
    respondGroup.add(vaca);
    respondGroup.add(thx);

    autoRespond.add(none);
    autoRespond.add(vaca);
    autoRespond.add(thx);

    none.setSelected(true);
    filters.add(autoRespond);
		 */
		return panel;
	}


	public JPanel buildPlafPanel() {

		JPanel panel = new JPanel();
		panel.setLayout( new ColumnLayout() );


		//plaf selection

		JPanel plafPanel = new JPanel();
		plafPanel.setBorder( new TitledBorder("Look And Feel") );
		plafPanel.setLayout(new ColumnLayout());


		plafGroup = new ButtonGroup();
		JRadioButton metal = new JRadioButton("Metal");
		JRadioButton windows = new JRadioButton("Windows");
		JRadioButton motif = new JRadioButton("Motif");

		plafGroup.add(metal);
		plafGroup.add(motif);
		plafGroup.add(windows);

		plafPanel.add(metal);
		plafPanel.add(motif);
		plafPanel.add(windows);

		metal.getModel().setActionCommand("metal");
		windows.getModel().setActionCommand("windows");
		motif.getModel().setActionCommand("motif");

		metal.setSelected(((String)god.fHash.get("plaf")).equals("metal"));
		windows.setSelected(((String)god.fHash.get("plaf")).equals("windows"));
		motif.setSelected(((String)god.fHash.get("plaf")).equals("motif"));

		metal.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) { 
				try {
					UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
					god.mainToolbar.setFloatable(true);
					god.mainToolbar.putClientProperty( "JToolBar.isRollover", Boolean.TRUE );
				}
				catch ( UnsupportedLookAndFeelException e ) {
					System.out.println ("Metal Look & Feel not supported on this platform.");

				}
				catch ( IllegalAccessException e ) {
					System.out.println ("Metal Look & Feel could not be accessed.");

				}
				catch ( ClassNotFoundException e ) {
					System.out.println ("Metal Look & Feel could not found.");

				}
				catch ( InstantiationException e ) {
					System.out.println ("Metal  Look & Feel could not be instantiated.");

				}
			}});

		motif.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) { 
				try {
					UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
					god.mainToolbar.setFloatable(true);
					god.mainToolbar.putClientProperty( "JToolBar.isRollover", Boolean.TRUE );
				}
				catch ( UnsupportedLookAndFeelException e ) {
					System.out.println (" Motif Look & Feel not supported on this platform.");

				}
				catch ( IllegalAccessException e ) {
					System.out.println (" Motif Look & Feel could not be accessed.");

				}
				catch ( ClassNotFoundException e ) {
					System.out.println (" Motif Look & Feel could not found.");

				}
				catch ( InstantiationException e ) {
					System.out.println ("Motif Look & Feel could not be instantiated. \nProgram Terminated");

				}
			}});  

		windows.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) { 
				try {
					UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
					god.mainToolbar.setFloatable(true);
					god.mainToolbar.putClientProperty( "JToolBar.isRollover", Boolean.TRUE );
				}
				catch ( UnsupportedLookAndFeelException e ) {
					System.out.println ("Windows Look & Feel not supported on this platform.");

				}
				catch ( IllegalAccessException e ) {
					System.out.println ("Windows Look & Feel could not be accessed.");

				}
				catch ( ClassNotFoundException e ) {
					System.out.println ("Windows Look & Feel could not found.");

				}
				catch ( InstantiationException e ) {
					System.out.println ("Windows Look & Feel could not be instantiated.");

				} 
			}})
			;


		//theme selection
		JPanel themePanel = new JPanel();
		themePanel.setBorder( new TitledBorder("Theme (Metal only):") );
		themePanel.setLayout(new ColumnLayout());

		themeGroup = new ButtonGroup();
		JRadioButton blue = new JRadioButton("The Dark Sky Of Bucharest");
		JRadioButton green = new JRadioButton("Green and Restless");
		JRadioButton contrast = new JRadioButton("Good old ED-011 b&w style");
		JRadioButton custom = new JRadioButton("custom");   

		blue.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) { 
				javax.swing.plaf.metal.MetalLookAndFeel.setCurrentTheme(new javax.swing.plaf.metal.DefaultMetalTheme());
			}});

		green.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) { 
				javax.swing.plaf.metal.MetalLookAndFeel.setCurrentTheme(new CustomMetalTheme(god.theProject.god.fHash));
			}});

		contrast.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) { 
				javax.swing.plaf.metal.MetalLookAndFeel.setCurrentTheme(new CustomMetalTheme(god.fHash));
				//todo
				//javax.swing.plaf.metal.MetalLookAndFeel.setCurrentTheme(new ContrastMetalTheme(theProject.god.fHash));
			}});

		custom.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) { 
				//todo
			}});  


		blue.getModel().setActionCommand("blue");
		green.getModel().setActionCommand("green");
		contrast.getModel().setActionCommand("bw");
		custom.getModel().setActionCommand("custom"); 

		blue.setSelected(((String)god.fHash.get("theme")).equals("blue"));
		green.setSelected(((String)god.fHash.get("theme")).equals("green"));
		contrast.setSelected(((String)god.fHash.get("theme")).equals("bw"));
		custom.setSelected(((String)god.fHash.get("theme")).equals("custom"));
		custom.setEnabled(false);   

		themeGroup.add(blue);   
		themeGroup.add(green);
		themeGroup.add(contrast);
		themeGroup.add(custom);

		themePanel.add(blue);
		themePanel.add(green);
		themePanel.add(contrast);
		themePanel.add(custom);


		panel.add(plafPanel);
		panel.add(themePanel);

		return panel;
	}

	public JPanel buildVerilogPanel() {

		JPanel panel = new JPanel();
		panel.setLayout( new ColumnLayout() );

		JPanel verilogPanel = new JPanel();
		verilogPanel.setBorder( new TitledBorder("Verilog interpretor options") );
		verilogPanel.setLayout(new ColumnLayout());

		saveBeforeRun = new JCheckBox("Save opened files before run",  ((Boolean)god.fHash.get("saveBeforeRun")).booleanValue());
		verilogPanel.add(saveBeforeRun);

		panel.add(verilogPanel);

		return panel;
	}


	public JPanel buildDirectoriesPanel() {

		JPanel panel = new JPanel();
		panel.setLayout( new ColumnLayout() );


		panel.setBorder( new TitledBorder("Directories options") );


		JTabbedPane dirTabs = new JTabbedPane();

		includeList = new JList();  //defined as members at the begining of file.
		modulesList = new JList();

		//includeList.setEditable(false);
		//modulesList.setEditable(false);

		JScrollPane includePane = new JScrollPane( includeList );
		JScrollPane modulesPane = new JScrollPane( modulesList );

		//todo: read dirs from prefs

		dirTabs.addTab("Include directories", null,  includePane );
		dirTabs.addTab("Precompiled modules directories", null, modulesPane );
		panel.add(dirTabs);

		JPanel buttonsPanel = new JPanel();
		buttonsPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));

		JButton addDirectory = new JButton("Add..");
		JButton editDirectory = new JButton("Edit..");
		JButton removeDirectory = new JButton("Remove");

		addDirectory.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) { 
				String selDir = new DirectoryChooser(thisPanel, "").getDirectory();   
			}});

		editDirectory.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) { 
				//todo
				//get active tab -> list
				//get from list
				String selDir = new DirectoryChooser(thisPanel, "").getDirectory();   
				//remove from list
				//add to list
			}});

		removeDirectory.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) { 
				//todo remove from list
			}});


		//editDirectory.setEnabled(false);

		buttonsPanel.add(addDirectory);
		buttonsPanel.add(editDirectory);
		buttonsPanel.add(removeDirectory);

		panel.add(buttonsPanel);






		//JComboBox dirSelectCombo = new JComboBox();
		//dirSelectCombo.addObject("Include directories");
		//dirSelectCombo.addObject("Precompiled modules directories");

		//panel.add(choseDirPanel, BorderLayout.NORTH);





		//saveBeforeRun = new JCheckBox("Save opened files before run",  ((Boolean)god.fHash.get("saveBeforeRun")).booleanValue());
		//verilogPanel.add(saveBeforeRun);

		//panel.add(verilogPanel);

		return panel;
	}






	protected void centerDialog() {
		Dimension screenSize = this.getToolkit().getScreenSize();
		Dimension size = this.getSize();
		screenSize.height = screenSize.height/2;
		screenSize.width = screenSize.width/2;
		size.height = size.height/2;
		size.width = size.width/2;
		int y = screenSize.height - size.height;
		int x = screenSize.width - size.width;
		this.setLocation(x,y);
	}

	/*  public void CancelPressed() {
    this.setVisible(false);
  }
	 */

	public void CancelPressed() {
		this.setVisible(false);
	}

	public void OKPressed() {
		//update the prefs file:

		/*

		 * ButtonGroup indentGroup;
		 * JTextField tabField;
		 * JTextField mrfField;
		 * JTextField mrpField;
		 * JCheckBox autosaveCheck;
		 * JTextField autosaveField;
		 * JCheckBox backupCheck;
		 * JCheckBox loadLastProjectCheck;
		 * JTextField undoField;
		 * ButtonGroup saveGroup;  
		 * ButtonGroup plafGroup;
		 * ButtonGroup themeGroup;


  JCheckBox saveBeforeRun;

		 */  

		String tempString;
		Integer tempInt;

		god.fHash.put("indentType",indentGroup.getSelection().getActionCommand());  
		god.fHash.put("save",saveGroup.getSelection().getActionCommand());  
		god.fHash.put("plaf",plafGroup.getSelection().getActionCommand());  
		god.fHash.put("theme",themeGroup.getSelection().getActionCommand());  

		god.fHash.put("autosave", new Boolean(((JToggleButton.ToggleButtonModel)autosaveCheck.getModel()).isSelected()));
		god.fHash.put("autobackup", new Boolean(((JToggleButton.ToggleButtonModel)backupCheck.getModel()).isSelected()));
		god.fHash.put("loadLastProject", new Boolean(((JToggleButton.ToggleButtonModel)loadLastProjectCheck.getModel()).isSelected()));

		god.fHash.put("saveBeforeRun", new Boolean(((JToggleButton.ToggleButtonModel)saveBeforeRun.getModel()).isSelected()));  


		try {

			tempString = tabField.getDocument().getText(0, tabField.getDocument().getLength()).trim();
			try {
				tempInt = new Integer(tempString);
				god.fHash.put("tabSize", tempInt); 
			} catch (NumberFormatException e) {
				//cannot convert editbox content into Integer
				//==>  the old value in the preferences is leaved unmodified. 
			}

			tempString = mrfField.getDocument().getText(0, mrfField.getDocument().getLength()).trim();
			try {
				tempInt = new Integer(tempString);
				god.fHash.put("mrf", tempInt); 
			} catch (NumberFormatException e) {
				//cannot convert editbox content into Integer
				//==>  the old value in the preferences is leaved unmodified. 
			}

			tempString = mrpField.getDocument().getText(0, mrpField.getDocument().getLength()).trim();
			try {
				tempInt = new Integer(tempString);
				god.fHash.put("mrp", tempInt); 
			} catch (NumberFormatException e) {
				//cannot convert editbox content into Integer
				//==>  the old value in the preferences is leaved unmodified. 
			}

			tempString = autosaveField.getDocument().getText(0, autosaveField.getDocument().getLength()).trim();
			try {
				tempInt = new Integer(tempString);
				god.fHash.put("autosaveTime", tempInt); 
			} catch (NumberFormatException e) {
				//cannot convert editbox content into Integer
				//==>  the old value in the preferences is leaved unmodified. 
			}

			tempString = undoField.getDocument().getText(0, undoField.getDocument().getLength()).trim();
			try {
				tempInt = new Integer(tempString);
				god.fHash.put("undoSize", tempInt); 
			} catch (NumberFormatException e) {
				//cannot convert editbox content into Integer
				//==>  the old value in the preferences is leaved unmodified. 
			}

		} catch (javax.swing.text.BadLocationException e) {
			System.out.println("Fatal exception: BadLocationException");
			System.out.println("!!!!  I don't know what to do !!!!");
		} 


		god.fHash.save();


		god.fHash.print();

		//todo:  notify the others for prefs changed.
		this.setVisible(false);
	}

}

class ColumnLayout implements LayoutManager {

	int xInset = 5;
	int yInset = 5;
	int yGap = 2;

	public void addLayoutComponent(String s, Component c) {}

	public void layoutContainer(Container c) {
		Insets insets = c.getInsets();
		int height = yInset + insets.top;

		Component[] children = c.getComponents();
		Dimension compSize = null;
		for (int i = 0; i < children.length; i++) {
			compSize = children[i].getPreferredSize();
			children[i].setSize(compSize.width, compSize.height);
			children[i].setLocation( xInset + insets.left, height);
			height += compSize.height + yGap;
		}

	}

	public Dimension minimumLayoutSize(Container c) {
		Insets insets = c.getInsets();
		int height = yInset + insets.top;
		int width = 0 + insets.left + insets.right;

		Component[] children = c.getComponents();
		Dimension compSize = null;
		for (int i = 0; i < children.length; i++) {
			compSize = children[i].getPreferredSize();
			height += compSize.height + yGap;
			width = Math.max(width, compSize.width + insets.left + insets.right + xInset*2);
		}
		height += insets.bottom;
		return new Dimension( width, height);
	}

	public Dimension preferredLayoutSize(Container c) {
		return minimumLayoutSize(c);
	}

	public void removeLayoutComponent(Component c) {}

}
